package org.chen.service.impl;

import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.chen.common.exception.ServiceException;
import org.chen.domain.dto.*;
import org.chen.domain.entity.*;
import org.chen.domain.response.PageResult;
import org.chen.domain.vo.AvatarConfigVO;
import org.chen.domain.vo.CommonConfigVO;
import org.chen.domain.vo.ConfigVO;
import org.chen.domain.vo.MultiAvatarConfigVO;
import org.chen.mapper.*;
import org.chen.service.ConfigService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class ConfigServiceImpl extends ServiceImpl<UserVideoConfigMapper,UserVideoConfig> implements ConfigService {

    @Autowired
    private UserVideoConfigMapper configMapper;

    @Autowired
    private AvatarMapper avatarMapper;

    @Autowired
    private VoiceMapper voiceMapper;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private AvatarConfigItemMapper avatarConfigItemMapper;

    @Autowired
    private MultiAvatarConfigMapper multiAvatarConfigMapper;

    @Override
    public List<ConfigVO> getMultiConfig() {
        List<MultiAvatarConfig> multiAvatarConfigList = multiAvatarConfigMapper.selectList(new LambdaQueryWrapper<MultiAvatarConfig>()
                .orderByDesc(MultiAvatarConfig::getCreateTime));

        return multiAvatarConfigList.stream().map(this::convertMultiToConfigVO)
                .toList();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveMultiAvatarConfig(MultiAvatarConfigDTO configDTO) {
        // 1. 验证每个数字人和语音的存在性以及匹配性
        validateMultiAvatarConfig(configDTO);

        // 2. 保存主配置
        MultiAvatarConfig config = new MultiAvatarConfig();
        config.setId(configDTO.getId());
        config.setName(configDTO.getName());
        config.setConfigType(configDTO.getConfigType());
        config.setIsDefault(false); // 默认为非默认配置
        config.setIsCaption(configDTO.getCommonConfig().getIsCaption());
        config.setIsOneToOne(configDTO.getCommonConfig().getOne_to_one());

        // 3. 序列化公共配置为JSON字符串
        try {
            // 确保公共配置中包含多背景相关字段
            CommonConfigDTO commonConfig = configDTO.getCommonConfig();

            // 如果单背景已设置但多背景未设置，则初始化多背景列表
            if (commonConfig.getBackgroundUrls() == null) {
                commonConfig.setBackgroundUrls(new ArrayList<>());
            }
            if (commonConfig.getBackgroundIds() == null) {
                commonConfig.setBackgroundIds(new ArrayList<>());
            }

            // 如果有背景URL但多背景列表为空，则添加单背景到多背景列表
            if (StringUtils.hasText(commonConfig.getBackgroundUrl()) && commonConfig.getBackgroundUrls().isEmpty()) {
                commonConfig.getBackgroundUrls().add(commonConfig.getBackgroundUrl());
                if (StringUtils.hasText(commonConfig.getBackgroundId())) {
                    commonConfig.getBackgroundIds().add(commonConfig.getBackgroundId());
                }
            }

            String commonConfigJson = objectMapper.writeValueAsString(configDTO.getCommonConfig());
            config.setCommonConfig(commonConfigJson);
        } catch (JsonProcessingException e) {
            throw new ServiceException("序列化公共配置失败: " + e.getMessage());
        }

        // 4. 保存或更新主配置
        if (configDTO.getId() != null) {
            // 更新主配置
            multiAvatarConfigMapper.updateById(config);

            // 删除原有数字人配置项
            avatarConfigItemMapper.delete(new LambdaQueryWrapper<AvatarConfigItem>()
                    .eq(AvatarConfigItem::getConfigId, config.getId()));
        } else {
            // 新增主配置
            multiAvatarConfigMapper.insert(config);
        }

        // 5. 保存数字人配置项
        List<AvatarConfigItem> items = new ArrayList<>();
        for (int i = 0; i < configDTO.getAvatarConfigs().size(); i++) {
            AvatarConfigDTO avatarConfig = configDTO.getAvatarConfigs().get(i);

            AvatarConfigItem item = new AvatarConfigItem();
            item.setConfigId(config.getId());
            item.setAvatarId(avatarConfig.getAvatarId());
            item.setVoiceId(avatarConfig.getVoiceId());
            item.setXOffset(avatarConfig.getXOffset());
            item.setYOffset(avatarConfig.getYOffset());
            item.setScale(avatarConfig.getScale());
            item.setItemOrder(i);

            items.add(item);
        }

        if (!items.isEmpty()) {
            avatarConfigItemMapper.batchInsert(items);
        }
    }

    @Override
    public MultiAvatarConfigVO getMultiAvatarConfig(String id) {
        // 1. 查询主配置
        MultiAvatarConfig config = multiAvatarConfigMapper.selectById(id);
        if (config == null) {
            throw new ServiceException("配置不存在");
        }

        // 2. 构建返回VO
        MultiAvatarConfigVO vo = new MultiAvatarConfigVO();
        vo.setId(config.getId());
        vo.setName(config.getName());
        vo.setConfigType(config.getConfigType());
        vo.setCreateTime(config.getCreateTime());
        vo.setUpdateTime(config.getUpdateTime());
        vo.setIsDefault(config.getIsDefault());
        vo.setIsCaption(config.getIsCaption());
        vo.setOne_to_one(config.getIsOneToOne());

        // 3. 反序列化公共配置
        try {
            CommonConfigVO commonConfig = objectMapper.readValue(config.getCommonConfig(), CommonConfigVO.class);
            vo.setCommonConfig(commonConfig);
        } catch (JsonProcessingException e) {
            throw new ServiceException("反序列化公共配置失败: " + e.getMessage());
        }

        // 4. 查询数字人配置项
        List<AvatarConfigItem> items = avatarConfigItemMapper.selectList(
                new LambdaQueryWrapper<AvatarConfigItem>()
                        .eq(AvatarConfigItem::getConfigId, config.getId())
                        .orderByAsc(AvatarConfigItem::getItemOrder)
        );

        // 5. 转换为VO列表
        List<AvatarConfigVO> avatarConfigs = new ArrayList<>();
        for (AvatarConfigItem item : items) {
            AvatarConfigVO avatarConfigVO = new AvatarConfigVO();
            avatarConfigVO.setAvatarId(item.getAvatarId());
            avatarConfigVO.setVoiceId(item.getVoiceId());
            avatarConfigVO.setXOffset(item.getXOffset());
            avatarConfigVO.setYOffset(item.getYOffset());
            avatarConfigVO.setScale(item.getScale());

            // 获取数字人详情
            VideoAvatar avatar = avatarMapper.selectOne(
                    new LambdaQueryWrapper<VideoAvatar>()
                            .eq(VideoAvatar::getAvatarId, item.getAvatarId())
            );
            avatarConfigVO.setAvatar(avatar);

            // 获取语音详情
            VideoVoice voice = voiceMapper.selectOne(
                    new LambdaQueryWrapper<VideoVoice>()
                            .eq(VideoVoice::getVoiceId, item.getVoiceId())
            );
            avatarConfigVO.setVoice(voice);

            avatarConfigs.add(avatarConfigVO);
        }

        vo.setAvatarConfigs(avatarConfigs);

        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMultiAvatarConfig(String id) {
        // 1. 检查配置是否存在
        MultiAvatarConfig config = multiAvatarConfigMapper.selectById(id);
        if (config == null) {
            throw new ServiceException("配置不存在");
        }

        // 2. 检查是否为默认配置
        if (Boolean.TRUE.equals(config.getIsDefault())) {
            throw new ServiceException("默认配置不能删除");
        }

        // 3. 删除数字人配置项
        avatarConfigItemMapper.delete(new LambdaQueryWrapper<AvatarConfigItem>()
                .eq(AvatarConfigItem::getConfigId, id));

        // 4. 删除主配置
        multiAvatarConfigMapper.deleteById(id);
    }

    /**
     * 验证多数字人配置的有效性
     */
    private void validateMultiAvatarConfig(MultiAvatarConfigDTO configDTO) {
        // 确保至少有一个数字人配置
        if (configDTO.getAvatarConfigs() == null || configDTO.getAvatarConfigs().isEmpty()) {
            throw new ServiceException("至少需要一个数字人配置");
        }

        // 验证每个数字人和语音
        for (AvatarConfigDTO avatarConfig : configDTO.getAvatarConfigs()) {
            VideoVoice voice = voiceMapper.selectOne(
                    new LambdaQueryWrapper<VideoVoice>()
                            .eq(VideoVoice::getVoiceId, avatarConfig.getVoiceId())
            );

            VideoAvatar avatar = avatarMapper.selectOne(
                    new LambdaQueryWrapper<VideoAvatar>()
                            .eq(VideoAvatar::getAvatarId, avatarConfig.getAvatarId())
            );

            if (voice == null) {
                throw new ServiceException("角色语音不存在");
            }

            if (avatar == null) {
                throw new ServiceException("虚拟角色不存在");
            }

            // 验证性别匹配（如需要）
            if (!avatar.getGender().equals("unknown")) {
                if (!voice.getGender().toLowerCase(Locale.ROOT).equals(avatar.getGender().toLowerCase(Locale.ROOT))) {
                    throw new ServiceException("角色性别与语音不匹配");
                }
            }
        }
    }

    /**
     * 将多数字人配置转换为通用配置VO
     */
    private ConfigVO convertMultiToConfigVO(MultiAvatarConfig config) {
        ConfigVO vo = new ConfigVO();
        vo.setId(config.getId());
        vo.setName(config.getName());
        vo.setConfigType("multiple");
        vo.setIsDefault(config.getIsDefault());
        vo.setIsCaption(config.getIsCaption());
        vo.setOne_to_one(config.getIsOneToOne());
        vo.setCreateTime(config.getCreateTime());
        vo.setUpdateTime(config.getUpdateTime());

        // 获取公共配置
        try {
            CommonConfigVO commonConfig = objectMapper.readValue(config.getCommonConfig(), CommonConfigVO.class);
            vo.setBackgroundType(commonConfig.getBackgroundType());
            vo.setBackgroundId(commonConfig.getBackgroundId());
            vo.setBackgroundUrl(commonConfig.getBackgroundUrl());
            // 新增多背景支持
            vo.setBackgroundUrls(commonConfig.getBackgroundUrls());
            vo.setBackgroundIds(commonConfig.getBackgroundIds());
            vo.setBackgroundColor(commonConfig.getBackgroundColor());
            vo.setBackgroundFit(commonConfig.getBackgroundFit());
            vo.setBackgroundPlayStyle(commonConfig.getBackgroundPlayStyle());
            vo.setWidth(commonConfig.getWidth());
            vo.setHeight(commonConfig.getHeight());
        } catch (JsonProcessingException e) {
            log.error("反序列化公共配置失败", e);
        }

        // 获取数字人数量
        long count = avatarConfigItemMapper.selectCount(
                new LambdaQueryWrapper<AvatarConfigItem>()
                        .eq(AvatarConfigItem::getConfigId, config.getId())
        );
        vo.setAvatarCount((int) count);

        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveConfig(ConfigDTO configDTO) {
        // 验证虚拟人物和语音是否存在
        validateConfig(configDTO);
        
        UserVideoConfig config = new UserVideoConfig();
        BeanUtils.copyProperties(configDTO, config);
        config.setIsAuto(false);
        
        if (configDTO.getId() != null) {
            // 更新
            configMapper.updateById(config);
        } else {
            // 新增
            configMapper.insert(config);
        }
    }

    @Override
    public PageResult<ConfigVO> getConfigList(ConfigQueryDTO queryDTO) {
        Page<UserVideoConfig> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());

        LambdaQueryWrapper<UserVideoConfig> wrapper = new LambdaQueryWrapper<UserVideoConfig>()
                .eq(StringUtils.isNotEmpty(queryDTO.getName()), UserVideoConfig::getName, queryDTO.getName())
                .eq(queryDTO.getIsDefault() != null, UserVideoConfig::getIsDefault, queryDTO.getIsDefault())
                .eq(StringUtils.isBlank(queryDTO.getConfigType()),
                        UserVideoConfig::getConfigType, "single")
                .eq(StringUtils.isNotBlank(queryDTO.getConfigType()),
                        UserVideoConfig::getConfigType, queryDTO.getConfigType())
                .orderByDesc(UserVideoConfig::getCreateTime);

        Page<UserVideoConfig> resultPage = configMapper.selectPage(page, wrapper);

        List<ConfigVO> voList = resultPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        // 如果查询多数字人配置或未指定配置类型
        if (StringUtils.isBlank(queryDTO.getConfigType()) || "multiple".equals(queryDTO.getConfigType())) {
            // 查询多数字人配置
            Page<MultiAvatarConfig> multiPage = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
            LambdaQueryWrapper<MultiAvatarConfig> multiWrapper = new LambdaQueryWrapper<MultiAvatarConfig>()
                    .eq(StringUtils.isNotBlank(queryDTO.getName()), MultiAvatarConfig::getName, queryDTO.getName())
                    .eq(queryDTO.getIsDefault() != null, MultiAvatarConfig::getIsDefault, queryDTO.getIsDefault())
                    .orderByDesc(MultiAvatarConfig::getCreateTime);

            Page<MultiAvatarConfig> multiResultPage = multiAvatarConfigMapper.selectPage(multiPage, multiWrapper);

            // 转换为ConfigVO
            List<ConfigVO> multiVoList = multiResultPage.getRecords().stream()
                    .map(this::convertMultiToConfigVO)
                    .toList();

            // 合并结果
            voList.addAll(multiVoList);

            // 更新总数
            long totalCount = resultPage.getTotal() + multiResultPage.getTotal();

            return new PageResult<>(voList, totalCount, resultPage.getSize(), resultPage.getCurrent());
        }

        return new PageResult<>(voList, resultPage.getTotal(), resultPage.getSize(), resultPage.getCurrent());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setDefaultConfig(String id) {
        // 更新当前配置为默认
        UserVideoConfig config = new UserVideoConfig();
        config.setId(id);
        config.setIsDefault(true);
        configMapper.updateById(config);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setCaptionConfig(String id) {
        // 更新当前配置为默认
        UserVideoConfig config = new UserVideoConfig();
        config.setId(id);
        config.setIsCaption(true);
        configMapper.updateById(config);
    }

    @Override
    public List<ConfigVO> getDefaultConfig() {
        List<UserVideoConfig> configs = configMapper.selectList(
                new LambdaQueryWrapper<UserVideoConfig>()
                        .orderByDesc(UserVideoConfig::getIsDefault)
                        .orderByDesc(UserVideoConfig::getCreateTime)
        );

        return new ArrayList<>(configs.stream()
                .map(this::convertToVO)
                .toList());
    }

    @Override
    public void deleteConfig(String id) {
        UserVideoConfig config = configMapper.selectById(id);
        if (config == null) {
            throw new ServiceException("配置不存在");
        }

        if (Boolean.TRUE.equals(config.getIsDefault())) {
            throw new ServiceException("默认配置不能删除");
        }

        avatarMapper.deleteById(config.getAvatarId());

        configMapper.deleteById(id);
    }

    @Override
    public void batchDelete(BatchConfigDeleteDTO request) {
        List<UserVideoConfig> userVideoConfigs = configMapper.selectBatchIds(request.getIds());
        Set<String> collect = userVideoConfigs.stream().map(UserVideoConfig::getAvatarId).collect(Collectors.toSet());
        avatarMapper.deleteByIds(collect);
        // 批量删除
        configMapper.deleteByIds(request.getIds());
    }

    private ConfigVO convertToVO(UserVideoConfig config) {
        ConfigVO vo = new ConfigVO();
        BeanUtils.copyProperties(config, vo);

        // 设置配置类型，默认为单数字人
        vo.setConfigType(config.getConfigType() != null ? config.getConfigType() : "single");

        // 获取虚拟人物详情
        if (StringUtils.hasText(config.getAvatarId())) {
            VideoAvatar avatar = avatarMapper.selectOne(
                    new LambdaQueryWrapper<VideoAvatar>()
                            .eq(VideoAvatar::getAvatarId, config.getAvatarId())
            );
            vo.setAvatar(avatar);
        }

        // 获取语音详情
        if (StringUtils.hasText(config.getVoiceId())) {
            VideoVoice voice = voiceMapper.selectOne(
                    new LambdaQueryWrapper<VideoVoice>()
                            .eq(VideoVoice::getVoiceId, config.getVoiceId())
            );
            vo.setVoice(voice);
        }

        return vo;
    }
    
    private void validateConfig(ConfigDTO configDTO) {
        VideoVoice voice = voiceMapper.selectOne(
                new LambdaQueryWrapper<VideoVoice>()
                        .eq(VideoVoice::getVoiceId, configDTO.getVoiceId())
        );

        VideoAvatar avatar = avatarMapper.selectOne(
                new LambdaQueryWrapper<VideoAvatar>()
                        .eq(VideoAvatar::getAvatarId, configDTO.getAvatarId())
        );

        if (voice == null) {
            throw new ServiceException("角色语音不存在");
        }

        if (avatar == null) {
            throw new ServiceException("虚拟角色不存在");
        }

        if (!avatar.getGender().equals("unknown")){
            if (!voice.getGender().toLowerCase(Locale.ROOT).equals(avatar.getGender().toLowerCase(Locale.ROOT))) {
                throw new ServiceException("角色性别与语音不匹配");
            }
        }
    }
}